using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace HalconDotNet
{
	internal class HTupleInt32 : HTupleImplementation
	{
		protected int[] i;

		public override int[] IArr
		{
			get
			{
				return i;
			}
			set
			{
				SetArray(value, copy: false);
			}
		}

		public override HTupleType Type => HTupleType.INTEGER;

		protected override Array CreateArray(int size)
		{
			return new int[size];
		}

		protected override void NotifyArrayUpdate()
		{
			i = (int[])data;
		}

		internal override void PinTuple()
		{
			Monitor.Enter(this);
			if (pinCount == 0)
			{
				pinHandle = GCHandle.Alloc(i, GCHandleType.Pinned);
			}
			pinCount++;
			Monitor.Exit(this);
		}

		public HTupleInt32(int i)
		{
			SetArray(new int[1]
			{
				i
			}, copy: false);
		}

		public HTupleInt32(int[] i, bool copy)
		{
			SetArray(i, copy);
		}

		public override HTupleElements GetElement(int index, HTuple parent)
		{
			return new HTupleElements(parent, this, index);
		}

		public override HTupleElements GetElements(int[] indices, HTuple parent)
		{
			if (indices == null || indices.Length == 0)
			{
				return new HTupleElements();
			}
			return new HTupleElements(parent, this, indices);
		}

		public override void SetElements(int[] indices, HTupleElements elements)
		{
			HTupleElementsInt32 hTupleElementsInt = new HTupleElementsInt32(this, indices);
			hTupleElementsInt.setI(elements.IArr);
		}

		public override int[] ToIArr()
		{
			return (int[])ToArray(typeI);
		}

		public override long[] ToLArr()
		{
			return (long[])ToArray(typeL);
		}

		public override double[] ToDArr()
		{
			return (double[])ToArray(typeD);
		}

		public override float[] ToFArr()
		{
			return (float[])ToArray(typeF);
		}

		public override IntPtr[] ToIPArr()
		{
			if (HalconAPI.isPlatform64)
			{
				base.ToIPArr();
			}
			IntPtr[] array = new IntPtr[iLength];
			for (int i = 0; i < iLength; i++)
			{
				array[i] = new IntPtr(this.i[i]);
			}
			return array;
		}

		public override int CopyToIArr(int[] dst, int offset)
		{
			Array.Copy(data, 0, dst, offset, iLength);
			return iLength;
		}

		public override int CopyToOArr(object[] dst, int offset)
		{
			for (int i = 0; i < iLength; i++)
			{
				dst[i + offset] = this.i[i];
			}
			return iLength;
		}

		public override int CopyFrom(HTupleImplementation impl, int offset)
		{
			return impl.CopyToIArr(i, offset);
		}

		public override void Store(IntPtr proc, int parIndex)
		{
			HalconAPI.HCkP(proc, HalconAPI.GetInputTuple(proc, parIndex, out IntPtr tuple));
			StoreData(proc, tuple);
		}

		protected override void StoreData(IntPtr proc, IntPtr tuple)
		{
			PinTuple();
			if (HalconAPI.isPlatform64)
			{
				HalconAPI.HCkP(proc, HalconAPI.CreateElementsOfType(tuple, base.Length, HTupleType.INTEGER));
				for (int i = 0; i < base.Length; i++)
				{
					HalconAPI.SetI(tuple, i, this.i[i]);
				}
			}
			else
			{
				HalconAPI.SetIArrPtr(tuple, this.i, iLength);
			}
		}

		public static int Load(IntPtr tuple, out HTupleInt32 data)
		{
			HalconAPI.GetTupleLength(tuple, out int length);
			int[] intArray = new int[length];
			int iArr = HalconAPI.GetIArr(tuple, intArray);
			data = new HTupleInt32(intArray, copy: false);
			return iArr;
		}
	}
}
